/*	COMP 6761 Assignment 1 Framework
	Created by Kaustubha Mendhurwar on 09/09/14.
	Copyright (c) 2014 Concordia University. All rights reserved.
*/

#pragma once
#include <string>
// Include GLEW - OpenGL Extension Wrangler
#define GLEW_STATIC
#include <GL/glew.h>
#include <memory>
#include <vector>
#include <GLM/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/common.hpp>
#include "Shader.hpp"
//

class Model
{
public:
		Model(std::string const & filename);
		~Model() {};

		struct mesh {

			mesh(std::vector<glm::vec3> const mesh_vertices, std::vector<GLuint> const & mesh_vertexIndices, std::vector<glm::vec3> const & mesh_normals);
			~mesh();
			void draw() const;
			GLuint mVertexBufferID;
			GLuint mVertexArrayIndicesId;
			GLuint mVertexArrayID;
			GLuint mVertexNormalId;

			std::vector<glm::vec3> vertices;
			std::vector<GLuint> vertexIndices;
			std::vector<glm::vec2> uvs;
			std::vector<glm::vec3> normals;


			std::vector<GLuint> primitiveAdjacencyIndices;
			std::vector<glm::vec3> discretePrimitives;
			std::vector<glm::vec3> discretePrimitivesAdjacency;

		};

		void Update(float dt);
		void Draw();

		glm::mat4 GetWorldMatrix() const;

		void SetPosition(glm::vec3 position);
		void SetScaling(glm::vec3 scaling);
		void SetRotation(glm::vec3 axis, float angleDegrees);

		glm::vec3 GetPosition() const		{ return mPosition; }
		glm::vec3 GetScaling() const		{ return mScaling; }
		glm::vec3 GetRotationAxis() const	{ return mRotationAxis; }
		float     GetRotationAngle() const	{ return mRotationAngleInDegrees; }

protected:
		
	void bindAttributes();
	void unbindAttributes();

	
	glm::vec3 mPosition;
	glm::vec3 mScaling;
	glm::vec3 mRotationAxis;
	float     mRotationAngleInDegrees;

	void loadObj(std::string const & path);


private:
		std::vector<std::unique_ptr<mesh>> meshes;
};
